package cn.test3d.activity;

import min3d.core.Object3dContainer;
import min3d.core.RendererActivity;
import min3d.objectPrimitives.SkyBox;
import min3d.parser.IParser;
import min3d.parser.Parser;
import min3d.vos.Light;
import min3d.vos.Number3d;
import android.content.pm.ActivityInfo;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import cn.sjj.util.Looger;
import cn.test3d.APP;
import cn.test3d.R;

public class MoveCameraActivity extends RendererActivity implements
		SensorEventListener, OnTouchListener {
	private int move = 0;
	private static final int MOVE_UP = 1;
	private static final int MOVE_DOWN = 2;
	private static final int MOVE_LEFT = 3;
	private static final int MOVE_RIGHT = 4;

	private final float FILTERING_FACTOR = .3f;

	private SkyBox mSkyBox;
	private SensorManager mSensorManager;
	private Sensor mAccelerometer;
	private Number3d mAccVals;
	private Object3dContainer mMonster;

	private RelativeLayout rl_main;
	private ImageView iv_move_main;
	private ImageView iv_move_cursor_up;
	private ImageView iv_move_cursor_down;
	private ImageView iv_move_cursor_left;
	private ImageView iv_move_cursor_right;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
		mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
		mAccelerometer = mSensorManager
				.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
		mAccVals = new Number3d();
		
		findView();
		registerListener();
	}
	
	private void registerListener() {
		// TODO Auto-generated method stub
		iv_move_cursor_up.setOnTouchListener(this);
		iv_move_cursor_down.setOnTouchListener(this);
		iv_move_cursor_left.setOnTouchListener(this);
		iv_move_cursor_right.setOnTouchListener(this);
	}

	private void findView() {
		rl_main = (RelativeLayout) findViewById(R.id.rl_main);
		rl_main.addView(_glSurfaceView);
		iv_move_cursor_up = (ImageView) findViewById(R.id.iv_move_cursor_up);
		iv_move_cursor_down = (ImageView) findViewById(R.id.iv_move_cursor_down);
		iv_move_cursor_left = (ImageView) findViewById(R.id.iv_move_cursor_left);
		iv_move_cursor_right = (ImageView) findViewById(R.id.iv_move_cursor_right);
		iv_move_main = (ImageView) findViewById(R.id.iv_move_main);
	}

	@Override
	protected void onCreateSetContentView() {
		// TODO Auto-generated method stub
		setContentView(R.layout.move_camera);
	}
	
	public void initScene() {

		scene.lights().add(new Light());
		
		scene.camera().position.rotateX(-45f);

		mSkyBox = new SkyBox(5.0f, 2);
		mSkyBox.addTexture(SkyBox.Face.North, R.drawable.wood_back, "north");
		mSkyBox.addTexture(SkyBox.Face.East, R.drawable.wood_right, "east");
		mSkyBox.addTexture(SkyBox.Face.South, R.drawable.wood_back, "south");
		mSkyBox.addTexture(SkyBox.Face.West, R.drawable.wood_left, "west");
		mSkyBox.addTexture(SkyBox.Face.Up, R.drawable.ceiling, "up");
		mSkyBox.addTexture(SkyBox.Face.Down, R.drawable.floor, "down");
		mSkyBox.scale().y = 0.8f;
		mSkyBox.scale().z = 2.0f;
		scene.addChild(mSkyBox);

		IParser parser = Parser.createParser(Parser.Type.MAX_3DS,
				getResources(), "cn.test3d:raw/monster_high", true);
		parser.parse();

		mMonster = parser.getParsedObject();
		mMonster.scale().x = mMonster.scale().y = mMonster.scale().z = .1f;
		mMonster.position().y = -2.5f;
		mMonster.position().z = -3;
		scene.addChild(mMonster);

		mSensorManager.registerListener(this, mAccelerometer,
				SensorManager.SENSOR_DELAY_UI);
	}

	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {
		// TODO Auto-generated method stub
	}

	@Override
	public void onSensorChanged(SensorEvent event) {
		if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER)
			return;

		// low-pass filter to make the movement more stable
//		mAccVals.x = (float) (-event.values[1] * FILTERING_FACTOR + mAccVals.x
//				* (1.0 - FILTERING_FACTOR));
//		mAccVals.y = (float) (event.values[0] * FILTERING_FACTOR + mAccVals.y
//				* (1.0 - FILTERING_FACTOR));
//
//		scene.camera().position.x = mAccVals.x * .2f;
//		scene.camera().position.y = mAccVals.y * .2f;
//
//		scene.camera().target.x = -scene.camera().position.x;
//		scene.camera().target.y = -scene.camera().position.y;
	}

	@Override
	public void updateScene() {
		// TODO Auto-generated method stub
		scene.camera().target.x = mMonster.position().x;
//		scene.camera().target.y = mMonster.position().y;
		scene.camera().target.z = mMonster.position().z;
		switch (move) {
		case MOVE_UP:
			scene.camera().position.z -= 0.5f;
			mMonster.position().z -= 0.5f;
			break;
		case MOVE_DOWN:
			scene.camera().position.z += 0.5f;
			mMonster.position().z += 0.5f;
			break;
		case MOVE_LEFT:
			scene.camera().position.x -= 0.5f;
			mMonster.position().x -= 0.5f;
			break;
		case MOVE_RIGHT:
			scene.camera().position.x += 0.5f;
			mMonster.position().x += 0.5f;
			break;
		}
	}
	
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		// TODO Auto-generated method stub
		switch (keyCode) {
		case KeyEvent.KEYCODE_VOLUME_UP:
			scene.camera().position.rotateX(-.1f);
			return true;
		case KeyEvent.KEYCODE_VOLUME_DOWN:
			scene.camera().position.rotateX(.1f);
			return true;
		}
		
		return super.onKeyDown(keyCode, event);
	}

	@Override
	public boolean onTouch(View v, MotionEvent event) {
		// TODO Auto-generated method stub
		int id = v.getId();
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			switch (id) {
			case R.id.iv_move_cursor_up:
				move = MOVE_UP;
				break;
			case R.id.iv_move_cursor_down:
				move = MOVE_DOWN;
				break;
			case R.id.iv_move_cursor_left:
				move = MOVE_LEFT;
				break;
			case R.id.iv_move_cursor_right:
				move = MOVE_RIGHT;
				break;
			}
			break;
		case MotionEvent.ACTION_MOVE:
			
			break;
		case MotionEvent.ACTION_UP:
			move = 0;
			break;
		}
		return true;
	}
}